package com.jyt.utils;

import chinavision.yjf.MVSDK;

public class GrabCmd {
	public static void main(String[] args) {

		// 枚举相机
		MVSDK.tSdkCameraDevInfo[] DevList = MVSDK.Api.CameraEnumerateDevice();
		int nDev = DevList.length;
		if (nDev < 1) {
			System.out.printf("No camera was found!\n");
			return;
		}

		MVSDK.tSdkCameraDevInfo DevInfo = DevList[0];
		PrintCameraDevInfo(DevInfo);

		// 打开相机
		int hCamera = 0;
		try {
			hCamera = MVSDK.Api.CameraInit(DevInfo, -1, -1);
		}
		catch (MVSDK.CameraException e) {
			System.out.printf("CameraInit Failed(%d): %s\n", e.errorCode, e.getMessage());
			return;
		}

		// 获取相机特性描述
		MVSDK.tSdkCameraCapbility cap = MVSDK.Api.CameraGetCapability(hCamera);
		PrintCapbility(cap);

		// 判断是黑白相机还是彩色相机
		boolean monoCamera = (cap.sIspCapacity.bMonoSensor != 0);

		// 黑白相机让ISP直接输出MONO数据，而不是扩展成R=G=B的24位灰度
		if (monoCamera) {
			MVSDK.Api.CameraSetIspOutFormat(hCamera, MVSDK.CAMERA_MEDIA_TYPE_MONO8);
		}

		// 相机模式切换成连续采集
		MVSDK.Api.CameraSetTriggerMode(hCamera, 0);

		// 手动曝光，曝光时间30ms
		MVSDK.Api.CameraSetAeState(hCamera, 0);
		MVSDK.Api.CameraSetExposureTime(hCamera, 30 * 1000);

		// 让SDK内部取图线程开始工作
		MVSDK.Api.CameraPlay(hCamera);

		// 计算RGB buffer所需的大小，这里直接按照相机的最大分辨率来分配
		int FrameBufferSize = cap.sResolutionRange.iWidthMax * cap.sResolutionRange.iHeightMax * (monoCamera ? 1 : 3);

		// 分配RGB buffer，用来存放ISP输出的图像
		// 备注：从相机传输到PC端的是RAW数据，在PC端通过软件ISP转为RGB数据（如果是黑白相机就不需要转换格式，但是ISP还有其它处理，所以也需要分配这个buffer）
		long pFrameBuffer = MVSDK.Api.CameraAlignMalloc(FrameBufferSize, 16);

		// 从相机取一帧图片
		try {
			MVSDK.tSdkFrameHead FrameHead = new MVSDK.tSdkFrameHead();
			long pRawData = MVSDK.Api.CameraGetImageBuffer(hCamera, FrameHead, 2000);
			MVSDK.Api.CameraImageProcess(hCamera, pRawData, pFrameBuffer, FrameHead);
			MVSDK.Api.CameraReleaseImageBuffer(hCamera, pRawData);
			
			// 此时图片已经存储在pFrameBuffer中，对于彩色相机pFrameBuffer=RGB数据，黑白相机pFrameBuffer=8位灰度数据
			// 该示例中我们只是把图片保存到硬盘文件中
			int status = MVSDK.Api.CameraSaveImage(hCamera, "z:\\grab.bmp", pFrameBuffer, FrameHead, monoCamera ? MVSDK.FILE_BMP_8BIT : MVSDK.FILE_BMP, 100);
			if (status == MVSDK.CAMERA_STATUS_SUCCESS) {
				System.out.printf("Save image successfully. image_size = %dX%d\n", FrameHead.iWidth, FrameHead.iHeight);
			}
			else {
				System.out.printf("Save image failed. err=%d\n", status);
			}
		} catch (MVSDK.CameraException e) {
			System.out.printf("CameraGetImageBuffer failed(%d): %s\n", e.errorCode, e.getMessage());
		}

		// 关闭相机
		MVSDK.Api.CameraUnInit(hCamera);

		// 释放帧缓存
		MVSDK.Api.CameraAlignFree(pFrameBuffer);
	}

	public static void PrintCameraDevInfo(MVSDK.tSdkCameraDevInfo Info) {
		System.out.printf("acProductSeries: %s\n", Info.getProductSeries());
		System.out.printf("acProductName: %s\n", Info.getProductName());
		System.out.printf("acFriendlyName: %s\n", Info.getFriendlyName());
		System.out.printf("acLinkName: %s\n", Info.getLinkName());
		System.out.printf("acDriverVersion: %s\n", Info.getDriverVersion());
		System.out.printf("acSensorType: %s\n", Info.getSensorType());
		System.out.printf("acPortType: %s\n", Info.getPortType());
		System.out.printf("acSn: %s\n", Info.getSn());
		System.out.printf("uInstance: %d\n", Info.uInstance);
	}

	public static void PrintCapbility(MVSDK.tSdkCameraCapbility cap) {
		for (int i = 0; i < cap.iTriggerDesc; ++i) {
			MVSDK.tSdkTrigger desc = cap.getTriggerDesc(i);
			System.out.printf("%d: %s\n", desc.iIndex, desc.getDescription());
		}
		for (int i = 0; i < cap.iImageSizeDesc; ++i) {
			MVSDK.tSdkImageResolution desc = cap.getImageSizeDesc(i);
			System.out.printf("%d: %s\n", desc.iIndex, desc.getDescription());
		}
		for (int i = 0; i < cap.iClrTempDesc; ++i) {
			MVSDK.tSdkColorTemperatureDes desc = cap.getClrTempDesc(i);
			System.out.printf("%d: %s\n", desc.iIndex, desc.getDescription());
		}
		for (int i = 0; i < cap.iMediaTypeDesc; ++i) {
			MVSDK.tSdkMediaType desc = cap.getMediaTypeDesc(i);
			System.out.printf("%d: %s\n", desc.iIndex, desc.getDescription());
		}
		for (int i = 0; i < cap.iFrameSpeedDesc; ++i) {
			MVSDK.tSdkFrameSpeed desc = cap.getFrameSpeedDesc(i);
			System.out.printf("%d: %s\n", desc.iIndex, desc.getDescription());
		}
		for (int i = 0; i < cap.iPackLenDesc; ++i) {
			MVSDK.tSdkPackLength desc = cap.getPackLenDesc(i);
			System.out.printf("%d: %s\n", desc.iIndex, desc.getDescription());
		}
		for (int i = 0; i < cap.iPresetLut; ++i) {
			MVSDK.tSdkPresetLut desc = cap.getPresetLutDesc(i);
			System.out.printf("%d: %s\n", desc.iIndex, desc.getDescription());
		}
		for (int i = 0; i < cap.iAeAlmSwDesc; ++i) {
			MVSDK.tSdkAeAlgorithm desc = cap.getAeAlmSwDesc(i);
			System.out.printf("%d: %s\n", desc.iIndex, desc.getDescription());
		}
		for (int i = 0; i < cap.iAeAlmHdDesc; ++i) {
			MVSDK.tSdkAeAlgorithm desc = cap.getAeAlmHdDesc(i);
			System.out.printf("%d: %s\n", desc.iIndex, desc.getDescription());
		}
		for (int i = 0; i < cap.iBayerDecAlmSwDesc; ++i) {
			MVSDK.tSdkBayerDecodeAlgorithm desc = cap.getBayerDecAlmSwDesc(i);
			System.out.printf("%d: %s\n", desc.iIndex, desc.getDescription());
		}
		for (int i = 0; i < cap.iBayerDecAlmHdDesc; ++i) {
			MVSDK.tSdkBayerDecodeAlgorithm desc = cap.getBayerDecAlmHdDesc(i);
			System.out.printf("%d: %s\n", desc.iIndex, desc.getDescription());
		}
	}
}
